﻿var GraphTemplates = function () {
    var getTemplate = function (name) {
        if (name == "linear") {
            return new linear();
        }
        if (name == "quadratic") {
            return new quadratic();
        }
        if (name == "quadraticv") {
            return new quadraticv();
        }
        if (name == "poly3") {
            return new poly3();
        }
        if (name == "sinewave") {
            return new sinewave();
        }
        if (name == "cosinewave") {
            return new cosinewave();
        }
        if (name == "exponential") {
            return new exponential();
        }
        if (name == "normal") {
            return new normal();
        }

    };

    var generateRandomColor = function () {
        
        var color = {};

        color.r = Math.floor(Math.random() * 256);
        do {
            color.g = Math.floor(Math.random() * 256);
        } while (Math.abs(color.g - color.r) < 35);

        do {
            color.b = Math.floor(Math.random() * 256);
        } while (Math.abs(color.b - color.g) < 35 || Math.abs(color.b - color.r) < 35);

        color.a = 1;

        return "rgba(" + color.r + "," + color.g + "," + color.b + "," + color.a + ")";
    };

    var linear = function () {
        this.name = "linear";
        this.type = "linear";
        this.form = "f(x) = mx + b";
        this.step = 100;
        this.lineColor = generateRandomColor();
        //pointColor: "red",
        this.lineWidth = 2;
        this.pointSize = 2;

        this.graphParams = {
            m: 1,
            b: 0
        };
        this.graphFunction = function (x) {
            var _p = this.graphParams;
            return _p.m * x + _p.b;
        }
    };
    var quadratic = function () {
        this.name = "quadratic";
        this.type = "quadratic";
        this.form = "f(x) = ax^2 + bx + c";
        this.step = 1;
        this.lineColor = generateRandomColor();
        //pointColor: "red",
        this.lineWidth = 2;
        this.pointSize = 2;

        this.graphParams = {
            a: 1,
            b: 0,
            c: 0
        };
        this.graphFunction = function (x) {
            var _p = this.graphParams;
            return _p.a * Math.pow(x, 2) + _p.b * x + _p.c;
        }

    };
    var quadraticv = function () {
        this.name = "quadratic vertex";
        this.type = "quadraticv";
        this.form = "f(x) = a (x - h)^2 + k";
        this.step = 1;
        this.lineColor = generateRandomColor();
        //pointColor: "red",
        this.lineWidth = 2;
        this.pointSize = 2;

        this.graphParams = {
            a: 1,
            h: 0,
            k: 0
        };
        this.graphFunction = function (x) {
            var _p = this.graphParams;
            return _p.a * Math.pow(x - _p.h, 2) + _p.k;
        }

    };
    var poly3 = function () {
        this.name = "polynomial (3)";
        this.type = "poly3";
        this.form = "f(x) = ax^3 + bx^2 + cx + d";
        this.step = 1;
        this.lineColor = generateRandomColor();
        //pointColor: "red",
        this.lineWidth = 2;
        this.pointSize = 2;

        this.graphParams = {
            a: 1,
            b: 1,
            c: 1,
            d: 0
        };
        this.graphFunction = function (x) {
            var _p = this.graphParams;
            return _p.a * Math.pow(x, 3) + _p.b * Math.pow(x, 2) + _p.c * x + _p.d;
        }

    };
    var sinewave = function () {
        this.name = "sine wave";
        this.type = "sinewave";
        this.form = "f(x) = a * sin(b * (x - c)) + d";
        this.step = 1;
        this.lineColor = generateRandomColor();
        //pointColor: "red",
        this.lineWidth = 2;
        this.pointSize = 2;

        this.graphParams = {
            a: 1,
            b: 1,
            c: 0,
            d: 0
        };
        this.graphFunction = function (x) {
            var _p = this.graphParams;
            return _p.a * Math.sin(_p.b * (x - _p.c)) + _p.d;
        }

    };
    var cosinewave = function () {
        this.name = "cosine wave";
        this.type = "cosinewave";
        this.form = "f(x) = a * cos(b * (x - c)) + d";
        this.step = 1;
        this.lineColor = generateRandomColor();
        //pointColor: "red",
        this.lineWidth = 2;
        this.pointSize = 2;

        this.graphParams = {
            a: 1,
            b: 1,
            c: 0,
            d: 0
        };
        this.graphFunction = function (x) {
            var _p = this.graphParams;
            return _p.a * Math.cos(_p.b *( x - _p.c)) + _p.d;
        }

    };
    
    var exponential = function () {
        this.name = "exponential";
        this.type = "exponential";
        this.form = "f(x) = k * a^(bx) + c";
        this.step = 1;
        this.lineColor = generateRandomColor();
        //pointColor: "red",
        this.lineWidth = 2;
        this.pointSize = 2;

        this.graphParams = {
            k: 1,
            a: 2,
            b: 1,
            c: 0
        };
        this.graphFunction = function (x) {
            var _p = this.graphParams;
            return _p.k * Math.pow(_p.a, x * _p.b) + _p.c;
        }

    };

    var normal = function () {
        this.name = "normal";
        this.type = "normal";
        this.form = "f(x) = 1 / ( s ( 2*pi )^(1/2) ) * e^( -(x - n)^2 / ( 2*s^2 )";
        this.step = 1;
        this.lineColor = generateRandomColor();
        //pointColor: "red",
        this.lineWidth = 2;
        this.pointSize = 2;

        this.graphParams = {
            mu: 0,
            sigma: 0.5
        };
        this.graphFunction = function (x) {
            var _p = this.graphParams;
            return Math.exp(-Math.pow(x - _p.mu, 2) / (2 * Math.pow(_p.sigma, 2))) / (_p.sigma * Math.pow(2 * Math.PI, 0.5));
        }

    };

    return {
        getTemplate: getTemplate
    };
};
